#include <ddm/ThriftServer.h>
#include <folly/logging/xlog.h>

namespace ddm {
ThriftServer::ThriftServer(std::shared_ptr<CtrlHandler>& handler)
    : ctrlHandler_{handler} {}

void ThriftServer::start() {
  CHECK(ctrlHandler_);
  auto server = std::make_unique<apache::thrift::ThriftServer>();
  server->setInterface(ctrlHandler_);
  server->setNumIOWorkerThreads(1);
  // Intentionally kept this as (1). If you're changing to higher number please
  // address thread safety for private member variables in OpenrCtrlHandler
  server->setNumCPUWorkerThreads(1);
  // Enable TOS reflection on the server socket
  server->setTosReflect(true);
  // Set the port and interface for OpenrCtrl thrift server
  server->setPort(2022);
  // Set workers join timeout.
  server->setWorkersJoinTimeout(std::chrono::seconds{2});

  thriftCtrlServerThreadVec_.emplace_back(std::thread([&]() noexcept {
    XLOG(INFO) << "Starting ThriftCtrlServer thread ...";
    folly::setThreadName("ddm-CtrlServer");
    server->serve();
    XLOG(INFO) << "ThriftCtrlServer thread got stopped.";
  }));

  // Wait until thrift server starts
  while (true) {
    auto evb = server->getServeEventBase();
    if (evb != nullptr and evb->isRunning()) {
      break;
    }
    std::this_thread::yield();
  }

  server_ = std::move(server);
}

void ThriftServer::stop() {
  XLOG(INFO) << "Calling ThriftCtrlServer stop.";
  server_->stop();  // Wait for all threads
  for (auto& thread : thriftCtrlServerThreadVec_) {
    thread.join();
  }
  server_.reset();
}
}  // namespace ddm